package com.clp.inflxudb.core;

import com.clp.inflxudb.core.domain.FluxKV;
import com.clp.inflxudb.core.domain.FluxKVGroup;
import com.clp.inflxudb.core.domain.TsRange;
import com.clp.inflxudb.core.enums.*;

import java.time.Instant;
import java.util.List;

public interface Flux {
    static Flux getInstance() {
        return new StrFlux();
    }

    static Flux getInstance(String name) {
        return new StrFlux(name);
    }

    /**
     * 定义数据源所在的桶（桶=数据库+保留策略）
     * @param bucketName：桶名称
     * @return：自身
     */
    Flux bucket(String bucketName);

    /**
     * 指定时间范围（必须）
     * @param startTime：开始时间
     * @param stopTime：结束时间
     * @param tsUnit：时间单位
     * @return：自身
     */
    Flux range(int startTime, int stopTime, TsUnit tsUnit);
    Flux range(Instant startTime, Instant stopTime);
    Flux range(TsRange tsRange);

    /**
     * 过滤数据
     * @param fluxKVList：键值对列表
     * @param logicOp：逻辑连接
     * @return：自身
     */
    Flux filter(List<FluxKV> fluxKVList, LogicOp logicOp);
    Flux filter(FluxKVGroup fluxKVGroup);
    Flux filterAnd(List<FluxKV> fluxKVList);
    Flux filterOr(List<FluxKV> fluxKVList);
    Flux filter(String keyStr, Object valueObj, CompareOp compareOp);
    Flux filter(FluxKV fluxKV);
    /**
     * 自定义语句
     * @param queryStr：flux查询语句
     * @return：自身
     */
    Flux filterCustom(String queryStr);

    /**
     * 根据时间段对数据进行分区
     * @param every：间隔时间
     * @param tsUnit：间隔时间单位
     * @return：自身
     */
    Flux window(int every, TsUnit tsUnit);

    Flux window(int every, TsUnit tsUnit, int offset, TsUnit offsetTsUnit);

    /**
     * 将所有点聚集到一个单一的inf窗口中
     * @return：自身
     */
    Flux windowInf();

    /**
     * window(int, TsUnit) + 辅助函数FluxFunc + window()
     * @param every：间隔时间
     * @param tsUnit：间隔时间单位
     * @param func：聚合函数枚举
     * @return：自身
     */
    Flux aggregateWindow(int every, TsUnit tsUnit, Func func);

    /**
     * 求表中的_value平均值
     * @return：自身
     */
    Flux mean();

    Flux mean(String columnName);

    Flux min();

    Flux min(String columnName);

    Flux max();

    Flux max(String columnName);

    Flux sum();

    Flux sum(String columnName);

    /**
     * 根据组键对表进行分组。
     * 组键：一个表中每行具有相同同值的一组键
     * @return：自身
     */
    Flux group(List<String> keyStrList, GroupMode groupMode);

    /**
     * 由于被聚合后，结果表没有列，可使用该方法将某一列复制出新的列
     * @param fromColumnName：被复制的列名
     * @param toColumnName：要复制到的列名
     * @return：自身
     */
    Flux duplicate(String fromColumnName, String toColumnName);

    /**
     * 删除列
     * @param keyStrList：键名列表
     * @return：自身
     */
    Flux drop(List<String> keyStrList);

    /**
     * 按值排序
     * @param desc：是否为降序
     * @return：自身
     */
    Flux sort(boolean desc);

    /**
     * 根据特定的列对表中的记录进行排序
     * @param keyStrList：键名列表
     * @return：自身
     */
    Flux sort(List<String> keyStrList, boolean desc);

    /**
     * 将输出表中的记录数限制为固定数num
     * @param offset：偏移量（从0开始）
     * @param num：数目
     * @return：自身
     */
    Flux limit(int offset, int num);

    /**
     * 映射
     * @param tblName：抽象的表名
     * @param keyStr：要改变的字段
     * @param execution：表达式
     * @return：自身
     */
    Flux map(String tblName, String keyStr, String execution);
    Flux map(String tblName, String execution);

    /**
     * 旋转
     * @param rowKey：行键
     * @param columnKey：列键
     * @param valueColumn：值列
     * @return：自身
     */
    Flux pivot(String rowKey, String columnKey, String valueColumn);

    /**
     * 默认旋转
     * @return：自身
     */
    Flux pivot();
    boolean isPivoted();

    /**
     * 跟踪表中多个列的增加
     * @return：自身
     */
    Flux increase();

    /**
     * 移动平均值
     * @param num：计算平均值的总数
     * @return：自身
     */
    Flux movingAverage(int num);

    /**
     * 基于时间中期的移动平均值
     * @param every：每隔多长时间计算一次
     * @param everyTsUnit：时间单位
     * @param period：计算的时间范围
     * @param periodTsUnit：时间单位
     * @return：自身
     */
    Flux timedMovingAverage(int every, TsUnit everyTsUnit, int period, TsUnit periodTsUnit);

    /**
     * 计算变化率
     * @param unit：每隔多久计算一次
     * @param tsUnit ：时间单位
     * @param nonNegative：是否忽略负变化率
     * @return：自身
     */
    Flux derivative(int unit, TsUnit tsUnit, boolean nonNegative);

    /**
     * 计算每个时间窗口的平均变化率
     * @param every：每隔多久计算一次
     * @param everyTsUnit：时间单位
     * @param unit：计算的时间范围
     * @param unitTsUnit：时间单位
     * @return：自身
     */
    Flux aggregateRate(int every, TsUnit everyTsUnit, int unit, TsUnit unitTsUnit);

//    Flux histogram(String )

    /**
     * 替换空值：使用前一个值
     * @param usePrevious：是否使用前一个值
     * @return：自身
     */
    Flux fill(boolean usePrevious);

    /**
     * 替换空值：使用指定的值
     * @param value：使用指定的值
     * @return：自身
     */
    Flux fill(int value);

    /**
     * 查找中值
     * @param medianMethod：中值方法
     * @return：自身
     */
    Flux median(MedianMethod medianMethod);

    /**
     * 查找分位数
     * @param q：分位值（0到1之间）
     * @param quantileMethod：分位数方法
     * @return：自身
     */
    Flux quantile(double q, QuantileMethod quantileMethod);

    /**
     * 查询累计总和
     * @return：自身
     */
    Flux cumulativeSum();

    /**
     * 查询第1条记录
     * @return：自身
     */
    Flux first();

    Flux first(String columnName);

    /**
     * 查询最后一条记录
     * @return：自身
     */
    Flux last();

    Flux last(String columnName);

    /**
     * 提取表
     * @param fluxKVList：键值对列表
     * @return：自身
     */
    Flux tableFind(List<FluxKV> fluxKVList);

    /**
     * 获取表中的一列
     * @param keyStr：键名
     * @return：自身
     */
    Flux getColumn(String keyStr);

    /**
     * 获取表中的一行
     * @param index：索引（从0开始）
     * @return：自身
     */
    Flux getRecord(int index);

    /**
     * 标准化不规则时间戳
     * @param unit：单位
     * @param tsUnit：时间单位
     * @return：自身
     */
    Flux truncateTimeColumn(int unit, TsUnit tsUnit);

    Flux count(String keyStr);

    /**
     * 添加任意语句
     * @param str
     * @return
     */
    Flux customClause(String str);

    /**
     * 提交
     * @param name：名称
     * @return：自身
     */
    String yield(String name);
    String yield();
}
